[快学Python3]XML解析处理 - Element Tree
点击上方蓝字“开源优测”一起玩耍
概述
本文就是python xml解析进行讲解,在python中解析xml有很多种方法,本文通过实例来讲解如何使用ElementTree来解析xml。对于其他的xml解析方法,请自行去查找资料。
请注意,本文不是ElementTree手册,不会将所有的特性进行演示,笔者从实际用到的一些关键特性进行实例演示,对于其他特性,大家可以参见官方文档学习和了解:
https://docs.python.org/3/library/xml.etree.elementtree.html
什么是ElementTree
ElementTree是Python提供解析xml的标准库,ElementTree中每个节点(即Element)具有如下属性:
tag: string对象,标识该元素类型
attrib:dictionnary对象,标识该元素属性
text:string对象,标识该元素的文本
tail:string对象,标识该元素可选的尾字符串
child elements: 标识子节点
注:Element类型是一种灵活的容器对象,用于在内存中存储结构化数据。
使用ElementTree的标准方式为:
try:
# 若想加快速度,可以使用C语言编译的API xml.etree.cElementTree。
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
或者直接:
import xml.etree.ElementTree as ET
从文件加载xml进行解析
本节通过加载一个已存在于硬盘的xml文件,示例演示,直接看代码。
将下列内容保存至本地任何目录下: data_demo.xml:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
下面我们解析上述data_demo.xml文档进行读、增、修改、删除操作
# -*- coding:utf-8 -*-
__author__ = '苦叶子'
try:
# 若想加快速度,可以使用C语言编译的API xml.etree.cElementTree。
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
if __name__ == "__main__":
print("解析本地data_demo.xml文档")
# 加载xml文件
tree = ET.parse("data_demo.xml")
# 获取根节点, 并打印节点文本:data
root = tree.getroot()
print(root.tag)
# 遍历输出country及其name属性
for child in root:
print(child.tag, "name:" ,child.attrib["name"])
# 遍历rank节点
# 我们借助iter迭代器来进行全迭代查找感兴趣的节点
# 输出节点tag及其文本
print("使用iter迭代器查找目标节点")
for rank in root.iter("rank"):
print(rank.tag, " - ", rank.text)
# 换一种方式来遍历rank节点
# 我们借助findall和find方法来查找感兴趣的节点
# 输出节点tag及其文本
# 注意:findall只能查找从当前节点的子节点查找目标节点
print("使用findall查找目标节点")
# 使用findall查找所有country节点,用于遍历
for country in root.findall("country"):
#print(country)
# 使用find从country节点中查找rank节点
rank = country.find("rank")
print(rank.tag, " - ", rank.text)
# 把所有的rank的文本都修改为: 开源优测
for rank in root.iter("rank"):
rank.text = "开源优测"
rank.set('updated', 'yes')
# 把修改后的rank的文本重新遍历打印出来,这时应该打印出: 开源优测
for rank in root.iter("rank"):
print(rank.text)
# 给所有的country新增一个<url>www.testingunion.com</url>节点
for country in root.iter("country"):
# 创建一个节点
url = ET.Element("url")
#print(url)
# 给节点url的text赋值
url.text = "www.testingunion.com"
# 将url节点追加到country节点下
country.append(url)
# 打印下整个xml出来看看是不是所有country节点都新增了一个url节点
for country in root.iter("country"):
# 查找url节点
url = country.find("url")
# 打印url的text
print(url.text)
# 删除year节点
for country in root.iter("country"):
year = country.find("year")
# 如果year节点存在,则删除
if year is not None:
print("删除了一个year节点")
country.remove(year)
# 保存上述 修改、新增、删除后的xml到 data_demo_new.xml中
# 大家自己打开data_demo_new.xml文档看修改、新增、删除的节点是否有效
tree.write("data_demo_new.xml", encoding="utf-8")
注: 用ET.fromstring("xml格式字符串") 替换ET.parse("data_demo.xml"),后续其他代码不变,即可实现对xml格式的字符串进行遍历读取、新增、修改和删除动作。
xpath支持
通过上面的实例我们基本学会了怎么对xml文档/xml格式的字符串进行遍历、新增、修改和删除操作,但对于xml怎么能缺少xpath的支持。
在ElementTree中,提供了良好的xpath特性支持,下面看一个实例
# -*- coding:utf-8 -*-
__author__ = '苦叶子'
try:
# 若想加快速度,可以使用C语言编译的API xml.etree.cElementTree。
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
if __name__ == "__main__":
print("Element Tree XPath特性支持示例")
# 加载xml文件
tree = ET.parse("data_demo.xml")
# 获取根节点, 并打印节点文本:data
root = tree.getroot()
# 选择当前节点, 返回的是当前节点对象列表
print("选择当前节点")
data = root.findall(".")
for d in data:
print(d.tag)
# 选择所有country节点
print("选择所有country节点方法一")
countrys = root.findall(".//country")
for country in countrys:
print(country.tag, " ", country.attrib["name"])
print("选择所有country节点方法二")
countrys = root.findall("country")
for country in countrys:
print(country.tag, " ", country.attrib["name"])
print("选择name属性为Panama的country节点")
countrys = root.findall(".//*[@name='Panama']")
for country in countrys:
print(country.tag, " ", country.attrib["name"])
# name属性为Panama的country下的year节点
print("name属性为Panama的country下的year节点")
years = root.findall(".//country[@name='Panama']/year")
for year in years:
print(year.text)
# 通过索引来选择country节点,选择第一个country节点
# 注意索引从 1 开始
print("通过索引来选择country节点,选择第一个country节点")
country = root.findall(".//country[1]")
for c in country:
print(c.tag, " ", c.attrib["name"])
# 通过子节点的文本内容来选择节点
# 选择子节点gdppc且其文本为59900 的country节点
# 请注意这返回的是gdppc的父节点
print("通过子节点的文本内容来选择节点")
gdppc = root.findall(".//*[gdppc='59900']")
for gd in gdppc:
print(gd.tag)
小结
本文就ElementTree解析xml的遍历、新增、修改、删除等操作进行了实例演示,并演示了其对XPath选择器的支持,但要注意的是其对XPath的支持是有限制的,并不支持所有的XPath语法。
开源优测
分享软件测试开源技术、经验、方案的首发平台
长按二维码/微信扫描 关注开源优测
QQ群:260407012
苦叶子私人微信:liyimin1912
有问题,可留言或加好友进微信群
苦叶子原创文章首发平台